package org.longteng.sensitive.utils;

import org.longteng.core.utils.Reflections;
import org.longteng.sensitive.annotation.EncryptField;
import org.longteng.sensitive.annotation.SensitiveDataEntity;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.core.annotation.AnnotationUtils;

import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 敏感数据验证类
 */
public class SensitiveUtil {
    /**
     * 线上运行后不修改，会影响已加密数据解密
     * Key length not 128/192/256 bits.
     * 128 位 对应的是 16 个字节
     * 192 位 对应的是 24 个字节
     * 256 位 对应的是 32 个字节
     */
    public static final String KEY_STR = "SHA@!81e46f7i7e2ld";
    public static final String IV_KEY = "02fsdf12345sfec1";

    /**
     * 判断一个类是否敏感类，即是否有注解 @SensitiveData
     * @param clazz
     * @return
     */
    public static boolean isSensitiveClass(Class<?> clazz){
        SensitiveDataEntity sensitiveData = AnnotationUtils.findAnnotation(clazz, SensitiveDataEntity.class);
        return ObjectUtils.isNotEmpty(sensitiveData);
    }
    /**
     * 获取敏感类里面的敏感字段
     * @param clazz
     * @return
     */
    public static List<Field> getSensitiveField(Class<?> clazz){
        List<Field> list = new ArrayList<>();
        Field[] fields = Reflections.getFields(clazz);
        for (Field fs: fields) {
            boolean annotationPresent = fs.isAnnotationPresent(EncryptField.class);
            if(annotationPresent){
                list.add(fs);
            }
        }
        return list;
    }


    /**
     * 破解时密匙长度是规定了的
     * 如果密匙长度有问题会报错：Key length not 128/192/256 bits.
     * 意思就比如密匙长度不是16位 就会报错~
     * 所以需要填充密匙长度
     *
     * @param s
     * @param length
     * @return
     */
    public static byte[] getBytes(String s, int length) {
        byte[] keys =  Objects.toString(s,"").getBytes(StandardCharsets.UTF_8);
        int fixLength = length - keys.length;
        if (keys.length < length) {
            byte[] S_bytes = new byte[length];
            System.arraycopy(keys, 0, S_bytes, 0, keys.length);
            for (int x = length - fixLength; x < length; x++) {
                S_bytes[x] = 0x00;
            }
            return S_bytes;
        } else {
            byte[] S_bytes = new byte[length];
            System.arraycopy(keys, 0, S_bytes, 0, length);
            return S_bytes;
        }
    }

}
